package com.whfc.iot.mach.codec;

import com.whfc.common.obd.ObdDataUtil;
import com.whfc.common.obd.ObdFrame;
import com.whfc.common.util.VersionUtil;
import com.whfc.iot.mach.constant.MsgConst;
import com.whfc.iot.mach.entity.MachMsg0x06;
import com.whfc.iot.util.ByteUtil;
import com.whfc.iot.util.MsgDataCodecUtil;
import io.netty.buffer.ByteBuf;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2019/7/17 9:32
 */
public class MachMsgDataCodec0x06 implements MachMsgDataCodec<MachMsg0x06> {

    public static final double GPS_MULTIPLY = 100000 * 60D;

    @Override
    public void decode(ByteBuf buf, MachMsg0x06 msg) {

        int readableBytes = buf.readableBytes();
        //工作状态
        int status = buf.readUnsignedByte();
        //时间
        Date time = MsgDataCodecUtil.readDateTime(buf);

        //数据帧
        int frameNum = buf.readUnsignedByte();
        List<ObdFrame> frameList = frameNum > 0 ? new ArrayList<>(frameNum) : Collections.EMPTY_LIST;
        for (int k = 0; k < frameNum; k++) {
            long frameId = buf.readUnsignedInt();
            int[] frameDataBytes = new int[8];
            for (int i = 0; i < frameDataBytes.length; i++) {
                frameDataBytes[i] = buf.readUnsignedByte();
            }
            String frameData = ByteUtil.toHexString(frameDataBytes);
            ObdFrame frame = new ObdFrame();
            frame.setFrameId(frameId);
            frame.setFrameData(frameData);
            frameList.add(frame);
        }

        //电池状态
        Integer batteryState = Integer.valueOf(buf.readUnsignedByte());
        //电池电量
        Integer batteryPower = Integer.valueOf(buf.readUnsignedByte());

        //gps标志
        int gpsFlag = buf.readUnsignedByte();
        String lngFlag = MsgConst.EAST;
        String latFlag = MsgConst.NORTH;
        switch (gpsFlag) {
            case MsgConst.GPS_FLAG_N_E:
                lngFlag = MsgConst.EAST;
                latFlag = MsgConst.NORTH;
                break;
            case MsgConst.GPS_FLAG_N_W:
                lngFlag = MsgConst.WEST;
                latFlag = MsgConst.NORTH;
                break;
            case MsgConst.GPS_FLAG_S_E:
                lngFlag = MsgConst.EAST;
                latFlag = MsgConst.SOUTH;
                break;
            case MsgConst.GPS_FLAG_S_W:
                lngFlag = MsgConst.WEST;
                latFlag = MsgConst.SOUTH;
                break;
        }

        //经度
        int lngD = buf.readUnsignedByte();
        int[] lngMBytes = new int[3];
        lngMBytes[0] = buf.readUnsignedByte();
        lngMBytes[1] = buf.readUnsignedByte();
        lngMBytes[2] = buf.readUnsignedByte();
        int lngM = ByteUtil.low3ByteToInt(lngMBytes);
        double lng = lngD + (double) lngM / GPS_MULTIPLY;

        //纬度
        int latD = buf.readUnsignedByte();
        int[] latMBytes = new int[3];
        latMBytes[0] = buf.readUnsignedByte();
        latMBytes[1] = buf.readUnsignedByte();
        latMBytes[2] = buf.readUnsignedByte();
        int latM = ByteUtil.low3ByteToInt(latMBytes);
        double lat = latD + (double) latM / GPS_MULTIPLY;

        //主机版本号
        int[] masterVerArr = new int[3];
        masterVerArr[0] = buf.readUnsignedByte();
        masterVerArr[1] = buf.readUnsignedByte();
        masterVerArr[2] = buf.readUnsignedByte();
        String masterVer = VersionUtil.getHardwareVersion(masterVerArr);

        msg.setStatus(status);
        msg.setTime(time);
        msg.setFrameNum(frameNum);
        msg.setFrameList(frameList);

        msg.setBatteryState(batteryState);
        msg.setBatteryPower(batteryPower);

        msg.setLngFlag(lngFlag);
        msg.setLatFlag(latFlag);
        msg.setLngWgs84(lng);
        msg.setLatWgs84(lat);
        msg.setMasterVerArr(masterVerArr);
        msg.setMasterVer(masterVer);
    }

    @Override
    public void encode(ByteBuf buf, MachMsg0x06 msg) {

        //终端工作状态
        buf.writeByte(msg.getStatus());

        //时间
        MsgDataCodecUtil.writeDateTime(buf, msg.getTime());

        //数据帧数量
        int frameNum = msg.getFrameNum();
        buf.writeByte(frameNum);

        //数据帧
        List<ObdFrame> frameList = msg.getFrameList();
        if (frameNum > 0 && frameList != null && !frameList.isEmpty()) {
            for (ObdFrame frame : frameList) {
                buf.writeInt(frame.getFrameId().intValue());
                int[] frameDataBytes = ObdDataUtil.translateFrameData(frame.getFrameData());
                for (int i = 0; i < frameDataBytes.length; i++) {
                    buf.writeByte(frameDataBytes[i]);
                }
            }
        }

        //电池状态
        buf.writeByte(msg.getBatteryState());

        //电量百分比
        buf.writeByte(msg.getBatteryPower());

        //GPS标志位(默认北纬/东经)
        int gpsFlag = 0x0F;
        if (MsgConst.NORTH.equals(msg.getLngFlag())) {
            gpsFlag &= 0xF0;
        }
        if (MsgConst.EAST.equals(msg.getLatFlag())) {
            gpsFlag &= 0x00;
        }
        buf.writeByte(gpsFlag);

        //经度
        int lngD = (int) msg.getLngWgs84();
        int lngM = (int) ((msg.getLngWgs84() - lngD) * GPS_MULTIPLY);
        buf.writeByte(lngD);
        buf.writeBytes(ByteUtil.extractLow3Byte(lngM));

        //纬度
        int latD = (int) msg.getLatWgs84();
        int latM = (int) ((msg.getLatWgs84() - latD) * GPS_MULTIPLY);
        buf.writeByte(latD);
        buf.writeBytes(ByteUtil.extractLow3Byte(latM));

        //主机版本号
        int[] masterVerArr = VersionUtil.parseHardvareVersion(msg.getMasterVer());
        for (int ver : masterVerArr) {
            buf.writeByte(ver);
        }
    }
}
